package com.hjl.sr.remoting;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.apache.commons.httpclient.methods.PostMethod;
import org.springframework.remoting.httpinvoker.CommonsHttpInvokerRequestExecutor;
import org.springframework.remoting.httpinvoker.HttpInvokerClientConfiguration;
import org.springframework.remoting.support.RemoteInvocationResult;

import com.hjl.sr.remoting.adaptor.CommonHttpClientMethod;
import com.hjl.sr.security.Encrypter;

/**
 * @author pister
 * 2012-12-17 下午08:36:00
 */
public class SecurityCommonsHttpInvokerRequestExecutor extends CommonsHttpInvokerRequestExecutor {

	private Encrypter encrypter;

	public SecurityCommonsHttpInvokerRequestExecutor(Encrypter encrypter) {
		super();
		this.encrypter = encrypter;
	}
	
	protected RemoteInvocationResult doExecuteRequest(
			HttpInvokerClientConfiguration config, ByteArrayOutputStream baos)
			throws IOException, ClassNotFoundException {
		PostMethod postMethod = createPostMethod(config);
		try {
			EncryptContextHolder.setEncryptContext(new HttpClientEncryptContext(new CommonHttpClientMethod(postMethod)));
			
			setRequestBody(config, postMethod, baos);
			executePostMethod(config, getHttpClient(), postMethod);
			validateResponse(config, postMethod);
			InputStream responseBody = getResponseBody(config, postMethod);
			return readRemoteInvocationResult(responseBody, config.getCodebaseUrl());
		}
		finally {
			EncryptContextHolder.clearEncryptContext();
			
			postMethod.releaseConnection();
		}
	}
	
	

	@Override
	protected InputStream decorateInputStream(InputStream is) throws IOException {
		return encrypter.decryptInputStream(is, EncryptContextHolder.getEncryptContext());
	}

	@Override
	protected OutputStream decorateOutputStream(OutputStream os) throws IOException {
		return encrypter.encryptOutputStream(os, EncryptContextHolder.getEncryptContext());
	}

	
}
